Q: MPEG-1 または MPEG-2 のムービーのビデオフレームレートを計算するにはどうすればよいでしょうか?
A: この情報を取得する最も簡単な方法は、この関数は QuickTime 5 で導入された、新しい MediaGetPublicInfo 関数を使うことです(「MediaHandlers.h」を参照)。この関数にセレクタ kMHInfoEncodedFrameRate を渡すだけです。
また、MPEG メディアについては、QuickTime 6 の不具合(r. 3236091)があり、MediaGetPublicInfo を呼び出してフレームレート情報を取得する前に、MoviesTask 関数を使ってムービーをタスク化する必要があります。
(新しい MPEG-4 形式を含む)ほかのメディア形式の場合は、GetMediaSampleCount (または GetMovieNextInterestingTime )を使ってフレーム数をカウントし、この値とともにメディアの再生時間とタイムスケールを使ってフレームレートを割り出すという「古い」方法でフレームレートを計算する必要があります。下のリスト 1 にこの方法を示します。
リスト 1 MPEG ムービーのビデオフレームレートの計算
| #include <QuickTime/QuickTime.h>
#define kCharacteristicHasVideoFrameRate FOUR_CHAR_CODE('vfrr')
#define kCharacteristicIsAnMpegTrack FOUR_CHAR_CODE('mpeg')
#define BailOnMoviesErr(err) {if (err) goto bail; }
OSErr GetMovieFPS(Movie theMovie, short *fps)
{
MediaHandler mpegMediaHandler = nil;
Track theTrack = nil;
Media myMedia = nil;
OSErr err = noErr;
Boolean isMpeg = false;
/* フレームレート値を初期化 */
*fps = 0;
if (theMovie == nil) goto bail;
/* ビデオトラックを取得 */
theTrack = GetMovieIndTrackType(theMovie,
1,
kCharacteristicHasVideoFrameRate,
movieTrackCharacteristic);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* トラックのメディアを取得 */
myMedia = GetTrackMedia(theTrack);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* メディアハンドラのコンポーネントへの参照を取得 */
mpegMediaHandler = GetMediaHandler(myMedia);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* これは mpeg メディアハンドラか? */
err = MediaHasCharacteristic(mpegMediaHandler,
kCharacteristicIsAnMpegTrack,
&isMpeg);
if ((err == noErr) && isMpeg)
{
MHInfoEncodedFrameRateRecord encodedFrameRate;
Size encodedFrameRateSize = sizeof(encodedFrameRate);
/* QuickTime の不具合により、フレームレート値を
取得する前にムービーをタスク化する必要がある */
MoviesTask( theMovie, 0 );
/* 静的なフレームレートを取得 */
err = MediaGetPublicInfo(mpegMediaHandler,
kMHInfoEncodedFrameRate,
&encodedFrameRate,
&encodedFrameRateSize);
if (err == noErr)
{
Fixed staticFrameRate = 0;
staticFrameRate = encodedFrameRate.encodedFrameRate;
/* この値を簡単にするために丸める。端数も取得するには、
この値を分析する */
*fps = FixRound(staticFrameRate);
}
}
else /* ここでは、MPEG 以外のメディアを扱うため、
「古い」方法を使う */
{
long sampleCount = 0;
/* メディアのサンプル数を取得 */
sampleCount = GetMediaSampleCount(myMedia);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
if (sampleCount)
{
TimeValue duration;
TimeValue timeScale;
Fixed staticFrameRate = 0;
double frameRate;
/* メディアの再生時間を取得 */
duration = GetMediaDuration(myMedia);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* メディアのタイムスケールを取得 */
timeScale = GetMediaTimeScale(myMedia);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* フレームレートを計算:
フレームレート =
(サンプル数 * メディアのタイムスケール)/ メディアの再生時間 */
frameRate = sampleCount*(double)timeScale/(double)duration;
staticFrameRate = X2Fix(frameRate);
/* この値を簡単にするために丸める - その上、この
値を分析して端数の 1 部分を得ることもできる */
*fps = FixRound(staticFrameRate);
}
}
bail:
return err;
}
|
もう 1 つの方法として、QTMTB 54 に記述されているように、GetMovieNextInterestingTime 関数を使って MPEG ビデオフレームをカウントし、次にメディアの再生時間とタイムスケールの値を使ってフレームレートを計算する方法もあります。下のリスト 2 のコードは、この方法を示しています。
リスト 2 - GetMovieNextInterestingTime を使用したフレームレートの計算
|
#include <QuickTime/QuickTime.h>
long GetFrameCount (Movie theMovie)
{
long frameCount = 0;
TimeValue curMovieTime;
if (theMovie == NULL)
goto bail;
// QuickTime 6 の不具合により、初めに
// ムービーをタスク化する必要がある
MoviesTask( theMovie, 0 );
curMovieTime = 0;
while( curMovieTime >= 0 )
{
GetMovieNextInterestingTime(
theMovie,
nextTimeStep,
0, NULL,
curMovieTime,
fixed1,
&curMovieTime,
NULL );
frameCount++;
}
frameCount--; // ムービーの最後に余分な時間をとるステップがある
bail:
return(frameCount);
}
OSErr GetMovieFPS(Movie theMovie, TimeValue *fps)
{
OSErr err = noErr;
TimeValue duration=0,
timeScale=0,
movieDurationInSeconds;
/* fps 値の初期化 */
*fps = 0;
/* ムービーの再生時間を取得 */
duration = GetMovieDuration(theMovie);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* ムービーのタイムスケールを取得 */
timeScale = GetMovieTimeScale(theMovie);
err = GetMoviesError();
BailOnMoviesErr(err != noErr);
/* ムービーの長さを秒単位で取得 */
movieDurationInSeconds = duration / timeScale;
/* フレームレートを計算 */
*fps = GetFrameCount (theMovie) / movieDurationInSeconds;
bail:
return(err) ;
}
|
[2003 年 4 月 21 日]
|